package de.arndt_panzer.bensgallery;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.media.ExifInterface;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore.Images.Thumbnails;
import android.util.Log;
import android.widget.Toast;

public class BitmapHelper {
	
	public static final String	TAG					= BitmapHelper.class.getSimpleName();
	
	public static final int		MEDIA_TYPE_IMAGE	= 1;
	public static final int		MEDIA_TYPE_VIDEO	= 2;
	
	private static int calculateInSampleSize(
												BitmapFactory.Options options,
												int reqWidth,
												int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;
		
		if (height > reqHeight || width > reqWidth) {
			
			final int halfHeight = height / 2;
			final int halfWidth = width / 2;
			inSampleSize = 2;
			
			// Calculate the largest inSampleSize value that is a power of 2 and keeps both
			// height and width larger than the requested height and width.
			while ((halfHeight / inSampleSize) > reqHeight
					&& (halfWidth / inSampleSize) > reqWidth) {
				inSampleSize *= 2;
			}
		}
		return inSampleSize;
	}
	
	public static Bitmap decodeSampledBitmap(String pathName,
												int reqWidth,
												int reqHeight) {
		try {
			Bitmap bmp;
			if (BitmapHelper.isMovie(new File(pathName))) {
				bmp = ThumbnailUtils.createVideoThumbnail(	pathName,
															Thumbnails.MICRO_KIND);
			} else {
				
				// First decode with inJustDecodeBounds=true to check dimensions
				final BitmapFactory.Options options = new BitmapFactory.Options();
				options.inJustDecodeBounds = true;
				BitmapFactory.decodeFile(pathName, options);
				int width = reqWidth;
				int height = reqHeight;
				
				// orient the image
				Matrix matrix = new Matrix();
				try {
					ExifInterface exif = new ExifInterface(pathName);
					int orientation = exif.getAttributeInt(	ExifInterface.TAG_ORIENTATION,
															1);
					switch (orientation) {
						case 3:
							matrix.postRotate(180);
							break;
						case 5:
						case 6:
						case 7:
							matrix.postRotate(90);
							width = reqHeight;
							height = reqWidth;
							break;
						case 8:
							matrix.postRotate(270);
							width = reqHeight;
							height = reqWidth;
							break;
					}
				} catch (IOException e) {
					;
				}
				
				// Calculate inSampleSize
				options.inSampleSize = calculateInSampleSize(options,
																width,
																height);
				// Decode bitmap with inSampleSize set
				options.inJustDecodeBounds = false;
				bmp = BitmapFactory.decodeFile(pathName, options);
				bmp = Bitmap.createBitmap(bmp,
											0,
											0,
											bmp.getWidth(),
											bmp.getHeight(),
											matrix,
											true);
			}
			return bmp;
		} catch (OutOfMemoryError e) {
			Log.e(TAG, "decodeSampledBitmap(): out of memory", e);
		}
		return null;
	}
	
	public static String getFileNameExtension(String filePath) {
		int i = filePath.lastIndexOf('.');
		if (i < 0) return "";
		return filePath.substring(i + 1);
	}
	
	public static boolean isSupportedMedia(File file) {
		String ext = getFileNameExtension(file.getName());
		return (file.isFile() && file.canRead()
		&& (ext.equalsIgnoreCase("jpg")
			|| ext.equalsIgnoreCase("jpeg")
			|| ext.equalsIgnoreCase("png")
			|| ext.equalsIgnoreCase("bmp")
			|| ext.equalsIgnoreCase("gif")
			|| ext.equalsIgnoreCase("tif")
			|| ext.equalsIgnoreCase("mp4")));
	}
	
	public static boolean isMovie(File file) {
		String ext = getFileNameExtension(file.getName());
		return (ext.equalsIgnoreCase("mp4"));
	}
	
	public static class MediaFileFilter implements FilenameFilter {
		@Override
		public boolean accept(File dir, String filename) {
			File file = new File(dir, filename);
			return (BitmapHelper.isSupportedMedia(file));
		}
	}
	
	/** Create a file Uri for saving an image or video */
	public static Uri getOutputMediaFileUri(int type) {
		return Uri.fromFile(getOutputMediaFile(type));
	}
	
	/** Create a File for saving an image or video */
	@SuppressLint("SimpleDateFormat")
	public static File getOutputMediaFile(int type) {
		// To be safe, you should check that the SDCard is mounted
		// using Environment.getExternalStorageState() before doing this.
		
		File mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
		// This location works best if you want the created images to be shared
		// between applications and persist after your app has been uninstalled.
		
		// Create the storage directory if it does not exist
		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdirs()) {
				Log.d(TAG, "getOutputMediaFile(): failed to create directory");
				return null;
			}
		}
		
		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		File mediaFile;
		if (type == MEDIA_TYPE_IMAGE) {
			mediaFile = new File(mediaStorageDir.getPath() + File.separator +
									"IMG_" + timeStamp + ".jpg");
		} else if (type == MEDIA_TYPE_VIDEO) {
			mediaFile = new File(mediaStorageDir.getPath() + File.separator +
									"VID_" + timeStamp + ".mp4");
		} else {
			return null;
		}
		
		return mediaFile;
	}
	
	public static class JpegStoreCallback implements PictureCallback {
		
		final Context	mContext;
		File			mPictureFile;
		
		public JpegStoreCallback(Context context) {
			mContext = context;
		}
		
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			
			mPictureFile = BitmapHelper.getOutputMediaFile(BitmapHelper.MEDIA_TYPE_IMAGE);
			if (mPictureFile == null) {
				Log.d(TAG, "onPictureTaken(): Can not create a picture file.");
			} else {
				
				try {
					FileOutputStream fos = new FileOutputStream(mPictureFile);
					fos.write(data);
					fos.close();
					Toast.makeText(mContext,
									"Bild gespeichert :-)",
									Toast.LENGTH_SHORT)
							.show();
					Log.d(	TAG,
							"onPictureTaken(): File " + mPictureFile.getAbsolutePath());
					return;
				} catch (FileNotFoundException e) {
					Log.d(	TAG,
							"onPictureTaken(): File not found: " + e.getMessage());
				} catch (IOException e) {
					Log.d(	TAG,
							"onPictureTaken(): Error accessing file: " + e.getMessage());
				}
			}
			
			Toast.makeText(	mContext,
							"Kann das Bild " + (mPictureFile != null ? mPictureFile.getAbsolutePath() + " "
																	: "")
								+ "nicht speichern :-(",
							Toast.LENGTH_LONG)
					.show();
			
		}
		
		public File getPictureFile() {
			return mPictureFile;
		}
		
	}
	
}
